{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fd4f9d65",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import functools\n",
    "from sklearn.datasets import load_iris\n",
    "import numpy as np\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0f5ac2eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = load_iris()\n",
    "y = list(iris.target)\n",
    "y_new = y\n",
    "for i in range(len(y)):\n",
    "    if y[i] == 0:\n",
    "        y_new[i] = [1,0,0]\n",
    "    elif y[i] == 1:\n",
    "        y_new[i] = [0,1,0]\n",
    "    else:\n",
    "        y_new[i] = [0,0,1]\n",
    "X = iris.data\n",
    "y = np.array(y_new)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "80c46200",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "import copy\n",
    "# 1. 加载数据并预处理\n",
    "# 加载鸢尾花数据集\n",
    "iris = datasets.load_iris()\n",
    "X = iris.data\n",
    "y = iris.target\n",
    "\n",
    "# 标准化数据\n",
    "scaler = StandardScaler()\n",
    "X = scaler.fit_transform(X)\n",
    "\n",
    "# 目标进行One-hot编码\n",
    "y_one_hot = np.zeros((y.size, y.max() + 1))\n",
    "y_one_hot[np.arange(y.size), y] = 1\n",
    "\n",
    "# 2. 拆分训练集和测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y_one_hot, test_size=0.02, random_state=42)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "ca9b3869",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "#计时器装饰器\n",
    "def time_it(func):\n",
    "    def wrapper(*args, **kwargs):\n",
    "        start_time = time.time()  # 记录开始时间\n",
    "        result = func(*args, **kwargs)  # 调用实际的函数\n",
    "        end_time = time.time()  # 记录结束时间\n",
    "        print(f\"Function '{func.__name__}' took {end_time - start_time:.4f} seconds to execute.\")\n",
    "        return result\n",
    "    return wrapper"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "98ba7403",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义激活函数和它们的导数\n",
    "class Sigmoid:\n",
    "    @staticmethod\n",
    "    def activate(x):\n",
    "        return 1 / (1 + np.exp(-x))\n",
    "\n",
    "    @staticmethod\n",
    "    def derivative(x):\n",
    "        return x * (1 - x)\n",
    "\n",
    "class Softmax:\n",
    "    @staticmethod\n",
    "    def activate(x):\n",
    "        exp_values = np.exp(x - np.max(x, axis=-1, keepdims=True))  # 稳定化计算，避免溢出\n",
    "        return exp_values / np.sum(exp_values, axis=-1, keepdims=True)\n",
    "\n",
    "    @staticmethod\n",
    "    def derivative(x):\n",
    "        s = x.reshape(-1, 1)\n",
    "        return np.diagflat(s) - np.dot(s, s.T)\n",
    "\n",
    "#定义优化器\n",
    "class optimizer:\n",
    "    def update_parameters(self,params,gradients):\n",
    "        pass\n",
    "\n",
    "#梯度下降优化器\n",
    "class GradientDescentOptimizer(optimizer):\n",
    "    def __init__(self,learning_rate=0.01):\n",
    "        self.learning_rate = learning_rate\n",
    "\n",
    "    def update_parameters(self,params,gradients):\n",
    "        updated_params = []\n",
    "        for param,gradient in zip(params,gradients):\n",
    "            updated_params.append(param - self.learning_rate * gradient)\n",
    "        return updated_params\n",
    "\n",
    "#Adam优化器\n",
    "class AdamOptimizer(optimizer):\n",
    "    def __init__(self, learing_rate, beta1=0.9, beta2=0.999, epsilon=1e-8):\n",
    "        \"\"\"\n",
    "        Adam优化器初始化\n",
    "\n",
    "        参数：\n",
    "        - params: 待优化的参数，通常是模型中的权重和偏置\n",
    "        - learning_rate: 学习率\n",
    "        - beta1: 一阶矩估计的衰减率，通常设为0.9\n",
    "        - beta2: 二阶矩估计的衰减率，通常设为0.999\n",
    "        - epsilon: 防止除零错误的常数，通常设为1e-8\n",
    "        \"\"\"\n",
    "        self.learning_rate = learing_rate\n",
    "        self.beta1 = beta1\n",
    "        self.beta2 = beta2\n",
    "        self.epsilon = epsilon\n",
    "        self.v = 0\n",
    "        self.t = 1\n",
    "        \n",
    "    def update_parameters(self,params,gradients):\n",
    "        updated_params = []\n",
    "        \n",
    "        v=0\n",
    "        #计算二阶矩动量\n",
    "        for param,gradient in zip(params,gradients):\n",
    "            v += np.sum(gradient**2)\n",
    "\n",
    "        #计算二阶矩动量加权，并重新更新\n",
    "        self.v = (1-self.beta2)*v+self.beta2*self.v\n",
    "        for i,(param,gradient) in enumerate(zip(params,gradients)):\n",
    "            #计算一阶矩动量\n",
    "            m = (1-self.beta1)*gradient + self.beta1*self.m[i]\n",
    "            #重新更新\n",
    "            self.m[i] = m\n",
    "            \n",
    "            #除以偏移量\n",
    "            m = m/(1-self.beta1**self.t)\n",
    "            v = self.v/(1-self.beta2**self.t)\n",
    "\n",
    "            #梯度更新\n",
    "            k = self.learning_rate  / (np.sqrt(v) + self.epsilon)\n",
    "            updated_params.append(param - k * m)\n",
    "        \n",
    "        self.t += 1\n",
    "\n",
    "        return updated_params\n",
    "    \n",
    "    def init_m(self,gradients):\n",
    "        self.m = [np.zeros_like(param) for param in gradients]\n",
    "\n",
    "class AFBMOptimizer(optimizer):\n",
    "    def __init__(self, learing_rate, beta1=0.9, beta2=0.999, epsilon=1e-8):\n",
    "        \"\"\"\n",
    "        Adam优化器初始化\n",
    "\n",
    "        参数：\n",
    "        - params: 待优化的参数，通常是模型中的权重和偏置\n",
    "        - learning_rate: 学习率\n",
    "        - beta1: 一阶矩估计的衰减率，通常设为0.9\n",
    "        - beta2: 二阶矩估计的衰减率，通常设为0.999\n",
    "        - epsilon: 防止除零错误的常数，通常设为1e-8\n",
    "        \"\"\"\n",
    "        self.learning_rate = learing_rate\n",
    "        self.beta1 = beta1\n",
    "        self.beta2 = beta2\n",
    "        self.epsilon = epsilon\n",
    "        self.v = 0\n",
    "        self.t = 1\n",
    "        \n",
    "    def update_parameters(self,params,gradients):\n",
    "        updated_params = []\n",
    "        \n",
    "        v=0\n",
    "        #计算二阶矩动量\n",
    "        for param,gradient in zip(params,gradients):\n",
    "            v += np.sum(gradient**2)\n",
    "\n",
    "        #计算二阶矩动量加权，并重新更新\n",
    "        self.v = (1-self.beta2)*v+self.beta2*self.v\n",
    "        for i,(param,gradient) in enumerate(zip(params,gradients)):\n",
    "            #计算一阶矩动量\n",
    "            m = (1-self.beta1)*gradient + self.beta1*self.m[i]\n",
    "            #重新更新\n",
    "            self.m[i] = m\n",
    "            \n",
    "            #除以偏移量\n",
    "            m = m/(1-self.beta1**self.t)\n",
    "            v = self.v/(1-self.beta2**self.t)\n",
    "\n",
    "            #梯度更新\n",
    "            k = self.learning_rate  / (np.sqrt(v) + self.epsilon)\n",
    "            updated_params.append(param - k * m)\n",
    "        \n",
    "        self.t += 1\n",
    "\n",
    "        return updated_params\n",
    "    \n",
    "    def init_m(self,gradients):\n",
    "        self.m = [np.zeros_like(param) for param in gradients]\n",
    "\n",
    "class FISTAOptimizer(optimizer):\n",
    "    def __init__(self, learing_rate):\n",
    "\n",
    "        self.learning_rate = learing_rate\n",
    "        self.t = 1\n",
    "        self.t_next = 1\n",
    "\n",
    "    def update_parameters(self,params,gradients):\n",
    "        updated_params = []\n",
    "\n",
    "        for i,(param,gradient) in enumerate(zip(params,gradients)):\n",
    "\n",
    "            updated_params.append(param-self.learning_rate*gradient)\n",
    "        \n",
    "\n",
    "        return updated_params\n",
    "    \n",
    "#class NesterovSpokoinyOptimizer(optimizer):\n",
    "#    def __init__(self,learning_rate=0.01):\n",
    "#        self.learning_rate = learning_rate\n",
    "#\n",
    "#    def update_parameters(self,params,gradients):\n",
    "#        updated_params = []\n",
    "#        for param,gradient in zip(params,gradients):\n",
    "#\n",
    "#            updated_params.append(param - self.learning_rate * gradient)\n",
    "#        return updated_params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "0039caf1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 神经网络类\n",
    "class NeuralNetwork:\n",
    "    def __init__(self, input_size, hidden_size, output_size, optimizer,learning_rate=0.1):\n",
    "        # 网络的初始化\n",
    "        np.random.seed(1)\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.output_size = output_size\n",
    "        self.learning_rate = learning_rate\n",
    "        self.optimizer = optimizer\n",
    "\n",
    "        # 初始化权重和偏置\n",
    "        self.weights_input_hidden = np.random.rand(input_size, hidden_size)  # 输入层到隐藏层的权重\n",
    "        self.weights_hidden_output = np.random.rand(hidden_size, output_size)  # 隐藏层到输出层的权重\n",
    "        self.bias_hidden = np.random.rand(hidden_size)  # 隐藏层偏置\n",
    "        self.bias_output = np.random.rand(output_size)  # 输出层偏置\n",
    "        \n",
    "        # 激活函数\n",
    "        self.activation = Sigmoid()\n",
    "        self.output_activation = Softmax()\n",
    "\n",
    "    def forward_propagation(self, inputs):\n",
    "\n",
    "        # 输入层到隐藏层的计算\n",
    "        hidden_layer_input = np.dot(inputs, self.weights_input_hidden) + self.bias_hidden\n",
    "        hidden_layer_output = self.activation.activate(hidden_layer_input)\n",
    "\n",
    "        # 隐藏层到输出层的计算\n",
    "        output_layer_input = np.dot(hidden_layer_output, self.weights_hidden_output) + self.bias_output\n",
    "        output_layer_output = self.output_activation.activate(output_layer_input)\n",
    "\n",
    "        return hidden_layer_output, output_layer_output\n",
    "\n",
    "    def __add__(self,other):\n",
    "        \n",
    "        temp_nn = copy.deepcopy(self)\n",
    "        temp_nn.weights_input_hidden = self.weights_input_hidden+other.weights_input_hidden  # 输入层到隐藏层的权重\n",
    "        temp_nn.weights_hidden_output = self.weights_hidden_output+other.weights_hidden_output   # 隐藏层到输出层的权重\n",
    "        temp_nn.bias_hidden = self.bias_hidden+other.bias_hidden  # 隐藏层偏置\n",
    "        temp_nn.bias_output = self.bias_output+other.bias_output  \n",
    "\n",
    "        return temp_nn\n",
    "    \n",
    "    def __mul__(self,other):\n",
    "\n",
    "        temp_nn = copy.deepcopy(self)\n",
    "        temp_nn.weights_input_hidden = self.weights_input_hidden*other # 输入层到隐藏层的权重\n",
    "        temp_nn.weights_hidden_output = self.weights_hidden_output*other   # 隐藏层到输出层的权重\n",
    "        temp_nn.bias_hidden = self.bias_hidden*other  # 隐藏层偏置\n",
    "        temp_nn.bias_output = self.bias_output*other\n",
    "\n",
    "        return temp_nn\n",
    "    \n",
    "    def backward_propagation(self, inputs, hidden_layer_output, output_layer_output, outputs):\n",
    "        # 计算输出层的误差\n",
    "        output_error = outputs - output_layer_output  # 均方误差的梯度\n",
    "        #print(output_error)\n",
    "        output = output_error  # 交叉熵的梯度与 Softmax 输出的导数在一块儿\n",
    "\n",
    "        # 计算隐藏层的误差\n",
    "        hidden_error = output.dot(self.weights_hidden_output.T)  # 输出层误差传播到隐藏层\n",
    "        hidden = hidden_error * self.activation.derivative(hidden_layer_output)\n",
    "\n",
    "        # 计算权重和偏置的梯度\n",
    "        weights_input_hidden_gradient = -np.dot(inputs.T, hidden)\n",
    "        weights_hidden_output_gradient = -np.dot(hidden_layer_output.T, output)\n",
    "        bias_hidden_gradient = -np.sum(hidden, axis=0)\n",
    "        bias_output_gradient = -np.sum(output, axis=0)\n",
    "\n",
    "        return [weights_input_hidden_gradient, weights_hidden_output_gradient, bias_hidden_gradient, bias_output_gradient]\n",
    "\n",
    "    def update_parameters(self, gradients, learning_rate=None):\n",
    "        params = [self.weights_input_hidden, self.weights_hidden_output, self.bias_hidden, self.bias_output]\n",
    "        updated_params = self.optimizer.update_parameters(params, gradients)\n",
    "        self.weights_input_hidden, self.weights_hidden_output, self.bias_hidden, self.bias_output = updated_params\n",
    "    \n",
    "    def predict(self, inputs):\n",
    "        # 预测函数\n",
    "        _, predicted_output = self.forward_propagation(inputs)\n",
    "        return predicted_output\n",
    "    \n",
    "    def train_option_decorator(func):\n",
    "        def wrapper(self,inputs,outputs,train_option,epochs):\n",
    "            if train_option == \"GD\":\n",
    "                return self.train_GD(inputs,outputs,epochs)\n",
    "            elif train_option == \"NSA\":\n",
    "                return self.train_NSA(inputs,outputs,epochs)\n",
    "            elif train_option == \"NSA_plus\":\n",
    "                return self.train_NSA_plus(inputs,outputs,epochs)\n",
    "            elif train_option == \"Adam\":\n",
    "                return self.train_Adam(inputs,outputs,epochs)\n",
    "            elif train_option == \"FISTA\":\n",
    "                return self.train_FISTA(inputs,outputs,epochs)\n",
    "        return wrapper\n",
    "    \n",
    "    @train_option_decorator\n",
    "    def train(self, inputs, outputs,train_option, epochs):\n",
    "        pass\n",
    "    \n",
    "    @time_it\n",
    "    def train_GD(self, inputs, outputs,epochs):\n",
    "\n",
    "        #记录训练过程中的损失\n",
    "        train_loss = []\n",
    "\n",
    "        # 训练网络\n",
    "        for epoch in range(epochs):\n",
    "\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "\n",
    "            # 反向传播\n",
    "            gradients = self.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "\n",
    "            # 更新参数\n",
    "            self.update_parameters(gradients)\n",
    "\n",
    "            loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "\n",
    "            # 每 1000 个epoch输出一次损失\n",
    "            #if epoch % 1000 == 0:\n",
    "            #    print(f\"Epoch {epoch}, Loss: {loss}\")\n",
    "                \n",
    "            train_loss.append(loss)\n",
    "        \n",
    "        return train_loss\n",
    "    \n",
    "    @time_it\n",
    "    def train_NSA(self, inputs, outputs, epochs):\n",
    "        \n",
    "        #记录训练过程中的损失\n",
    "        train_loss = []\n",
    "        nn_y = copy.deepcopy(self)\n",
    "        nn_x = copy.deepcopy(self)\n",
    "        nn_z = copy.deepcopy(self)\n",
    "        \n",
    "        # 训练网络\n",
    "        for epoch in range(epochs-1):\n",
    "            if epoch==0:\n",
    "                hidden_layer_output, output_layer_output = nn_y.forward_propagation(inputs)\n",
    "                loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "                train_loss.append(loss)\n",
    "                \n",
    "            epoch = epoch+1\n",
    "            #alpha_t\n",
    "            alpha = 5/(epoch+5)\n",
    "            ###y = (1-alpha)*x+alpha*z\n",
    "            nn_y = nn_x*(1-alpha)+nn_z*alpha\n",
    "\n",
    "            ## x = y-eta*grad(y)\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = nn_y.forward_propagation(inputs)\n",
    "            # 反向传播\n",
    "            y_gradients = nn_y.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "\n",
    "            #将nn_y的参数赋值给nn_x\n",
    "            nn_x = copy.deepcopy(nn_y)\n",
    "            #更新nn_x参数\n",
    "            nn_x.update_parameters(y_gradients)\n",
    "            \n",
    "            ###z = z-eta/alpha*grad(y)\n",
    "            new_y_gradients = [item/alpha for item in y_gradients]\n",
    "            nn_z.update_parameters(new_y_gradients)\n",
    "            self = copy.deepcopy(nn_x)\n",
    "            # 前向传播计算当前损失\n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "            \n",
    "            loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "\n",
    "            # 每 1000 个epoch输出一次损失\n",
    "            #print(f\"Epoch {epoch}, Loss: {loss}\")\n",
    "                \n",
    "            train_loss.append(loss)\n",
    "        return train_loss,self\n",
    "    \n",
    "    @time_it\n",
    "    def train_NSA_plus(self, inputs, outputs, epochs):\n",
    "        #记录训练过程中的损失\n",
    "        train_loss = []\n",
    "        nn_y = copy.deepcopy(self)\n",
    "        nn_x = copy.deepcopy(self)\n",
    "        nn_z = copy.deepcopy(self)\n",
    "        \n",
    "        # 训练网络\n",
    "        for epoch in range(epochs-1):\n",
    "            if epoch==0:\n",
    "                hidden_layer_output, output_layer_output = nn_y.forward_propagation(inputs)\n",
    "                loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "                train_loss.append(loss)\n",
    "                \n",
    "            epoch = epoch+1\n",
    "\n",
    "            #alpha_t\n",
    "            alpha = 5/(epoch+5)\n",
    "\n",
    "            ###y = (1-alpha)*x+alpha*z\n",
    "            nn_y = nn_x*(1-alpha)+nn_z*alpha\n",
    "\n",
    "            ## x1 = y-eta*grad(y)\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = nn_y.forward_propagation(inputs)\n",
    "            # 反向传播\n",
    "            y_gradients = nn_y.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "            \n",
    "            #梯度下降更新nn_y参数\n",
    "            nn_y.update_parameters(y_gradients)\n",
    "            \n",
    "            ## x2 = x-eta*grad(x)\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = nn_x.forward_propagation(inputs)\n",
    "            # 反向传播\n",
    "            x_gradients = nn_x.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "            \n",
    "            #梯度下降更新nn_y参数\n",
    "            nn_x.update_parameters(x_gradients)\n",
    "            #前向传播比较损失\n",
    "            hidden_layer_output,output_layer_output_y = nn_y.forward_propagation(inputs)\n",
    "            loss_y = np.mean(np.square(outputs - output_layer_output_y))\n",
    "            hidden_layer_output,output_layer_output_x = nn_x.forward_propagation(inputs)\n",
    "            loss_x = np.mean(np.square(outputs - output_layer_output_x))\n",
    "            \n",
    "            #print(\"C\",loss_x,loss_y)\n",
    "            if loss_y<loss_x:\n",
    "                nn_x = copy.deepcopy(nn_y)\n",
    "            elif loss_x<=loss_y:\n",
    "                nn_x = copy.deepcopy(nn_x)\n",
    "            ###z = z-eta/alpha*grad(y)\n",
    "            new_y_gradients = [item/alpha for item in y_gradients]\n",
    "            nn_z.update_parameters(new_y_gradients)\n",
    "            self = copy.deepcopy(nn_x)\n",
    "\n",
    "            # 前向传播计算当前损失\n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "            \n",
    "            loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "                \n",
    "            train_loss.append(loss)\n",
    "        return train_loss,self\n",
    "    \n",
    "    @time_it\n",
    "    def train_Adam(self, inputs, outputs, epochs):\n",
    "        #记录训练过程中的损失\n",
    "        train_loss = []\n",
    "\n",
    "        # 前向传播\n",
    "        hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "        # 反向传播\n",
    "        gradients = self.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "\n",
    "        #初始化梯度\n",
    "        self.optimizer.init_m(gradients)\n",
    "\n",
    "        # 训练网络\n",
    "        for epoch in range(epochs):\n",
    "\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "\n",
    "            # 反向传播\n",
    "            gradients = self.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "\n",
    "            # 更新参数\n",
    "            self.update_parameters(gradients)\n",
    "\n",
    "            loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "\n",
    "            train_loss.append(loss)\n",
    "        \n",
    "        return train_loss,self\n",
    "    \n",
    "    @time_it\n",
    "    def train_FISTA(self, inputs, outputs, epochs):\n",
    "        #记录训练过程中的损失\n",
    "        train_loss = []\n",
    "\n",
    "        t = 1\n",
    "        # 训练网络\n",
    "        for epoch in range(epochs):\n",
    "\n",
    "            nn_x_k = copy.deepcopy(self)\n",
    "\n",
    "            # 前向传播\n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "\n",
    "            # 反向传播\n",
    "            gradients = self.backward_propagation(inputs, hidden_layer_output, output_layer_output, outputs)\n",
    "\n",
    "            # 更新参数\n",
    "            self.update_parameters(gradients)\n",
    "\n",
    "            nn_x_k_plus_1 = copy.deepcopy(self)\n",
    "\n",
    "            momentum = nn_x_k_plus_1 + nn_x_k*(-1)\n",
    "\n",
    "            t_next = (1+math.sqrt(1+4*t**2))/2\n",
    "\n",
    "            self = nn_x_k_plus_1 + momentum*((t-1)/t_next)\n",
    "\n",
    "            t = t_next\n",
    "            \n",
    "            hidden_layer_output, output_layer_output = self.forward_propagation(inputs)\n",
    "\n",
    "            loss = np.mean(np.square(outputs - output_layer_output))  # 均方误差损失\n",
    "\n",
    "            train_loss.append(loss)\n",
    "        \n",
    "        return train_loss,self\n",
    "    \n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "f9113f9f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0, Loss: 0.26119357499848134\n"
     ]
    }
   ],
   "source": [
    "#实验1\n",
    "# 3. 初始化神经网络\n",
    "input_size = X_train.shape[1]  # 输入层大小（特征数量）\n",
    "hidden_size = 5  # 隐藏层大小\n",
    "output_size = y_train.shape[1]  # 输出层大小（三个类别）\n",
    "learning_rate = 0.08 # 学习率\n",
    "max_epochs = 40\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "\n",
    "# 4. 训练神经网络\n",
    "nn_NSA_plus = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA_plus,nn_NSA_plus = nn_NSA_plus.train(X_train, y_train,\"NSA_plus\", epochs=max_epochs)\n",
    "\n",
    "nn_NSA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA,nn_NSA = nn_NSA.train(X_train, y_train,\"NSA\", epochs=max_epochs)\n",
    "\n",
    "nn_GD = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_GD = nn_GD.train(X_train, y_train,\"GD\", epochs=max_epochs)\n",
    "\n",
    "optimizer = AdamOptimizer(learning_rate,beta1=0.9,beta2=0.999,epsilon=1e-8)\n",
    "nn_Adam = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_Adam,nn_Adam = nn_Adam.train(X_train, y_train,\"Adam\", epochs=max_epochs)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "f619d0a4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0, Loss: 0.26119357499848134\n",
      "Epoch 1000, Loss: 0.005666532956485016\n",
      "Epoch 2000, Loss: 0.004604593868226628\n",
      "Epoch 3000, Loss: 0.0003581061071376498\n",
      "Epoch 4000, Loss: 3.601882669102772e-05\n",
      "Epoch 5000, Loss: 1.1968380766763811e-05\n",
      "Epoch 6000, Loss: 5.776870908683219e-06\n",
      "Epoch 7000, Loss: 3.3516319221480577e-06\n",
      "Epoch 8000, Loss: 2.1694912903914496e-06\n",
      "Epoch 9000, Loss: 1.5100858624159575e-06\n"
     ]
    }
   ],
   "source": [
    "#实验2\n",
    "# 3. 初始化神经网络\n",
    "input_size = X_train.shape[1]  # 输入层大小（特征数量）\n",
    "hidden_size = 5  # 隐藏层大小\n",
    "output_size = y_train.shape[1]  # 输出层大小（三个类别）\n",
    "learning_rate = 0.07 # 学习率\n",
    "max_epochs = 10000\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "\n",
    "# 4. 训练神经网络\n",
    "nn_NSA_plus = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA_plus,nn_NSA_plus = nn_NSA_plus.train(X_train, y_train,\"NSA_plus\", epochs=max_epochs)\n",
    "\n",
    "nn_NSA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA,nn_NSA = nn_NSA.train(X_train, y_train,\"NSA\", epochs=max_epochs)\n",
    "\n",
    "nn_GD = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_GD = nn_GD.train(X_train, y_train,\"GD\", epochs=max_epochs)\n",
    "\n",
    "optimizer = AdamOptimizer(learning_rate,beta1=0.5,beta2=0.5,epsilon=1e-8)\n",
    "nn_Adam = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_Adam,nn_Adam= nn_Adam.train(X_train, y_train,\"Adam\", epochs=max_epochs)\n",
    "\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "nn_FISTA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_FISTA,nn_FISTA= nn_FISTA.train(X_train, y_train,\"FISTA\", epochs=max_epochs)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf988a91",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0, Loss: 0.26119357499848134\n",
      "Epoch 1000, Loss: 0.002498410577300696\n",
      "Epoch 2000, Loss: 1.7708829863644424e-05\n",
      "Epoch 3000, Loss: 4.193707617168944e-06\n",
      "Epoch 4000, Loss: 1.795752606134221e-06\n",
      "Epoch 5000, Loss: 9.821672268951658e-07\n",
      "Epoch 6000, Loss: 6.136214349419705e-07\n",
      "Epoch 7000, Loss: 4.1702569522287684e-07\n",
      "Epoch 8000, Loss: 3.004218794008225e-07\n",
      "Epoch 9000, Loss: 2.258938464193037e-07\n"
     ]
    }
   ],
   "source": [
    "#实验2\n",
    "# 3. 初始化神经网络\n",
    "input_size = X_train.shape[1]  # 输入层大小（特征数量）\n",
    "hidden_size = 5  # 隐藏层大小\n",
    "output_size = y_train.shape[1]  # 输出层大小（三个类别）\n",
    "learning_rate = 0.12 # 学习率\n",
    "max_epochs = 50000\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "\n",
    "# 4. 训练神经网络\n",
    "nn_NSA_plus = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA_plus,nn_NSA_plus = nn_NSA_plus.train(X_train, y_train,\"NSA_plus\", epochs=max_epochs)\n",
    "\n",
    "nn_NSA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA,nn_NSA = nn_NSA.train(X_train, y_train,\"NSA\", epochs=max_epochs)\n",
    "\n",
    "nn_GD = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_GD = nn_GD.train(X_train, y_train,\"GD\", epochs=max_epochs)\n",
    "\n",
    "optimizer = AdamOptimizer(learning_rate,beta1=0.5,beta2=0.5,epsilon=1e-8)\n",
    "nn_Adam = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_Adam,nn_Adam= nn_Adam.train(X_train, y_train,\"Adam\", epochs=max_epochs)\n",
    "\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "nn_FISTA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_FISTA,nn_FISTA= nn_FISTA.train(X_train, y_train,\"FISTA\", epochs=max_epochs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "86e5e8b2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Function 'train_NSA_plus' took 6.5631 seconds to execute.\n",
      "Function 'train_NSA' took 4.5560 seconds to execute.\n",
      "Function 'train_GD' took 1.2177 seconds to execute.\n",
      "Function 'train_Adam' took 1.9411 seconds to execute.\n",
      "Function 'train_FISTA' took 4.8830 seconds to execute.\n"
     ]
    }
   ],
   "source": [
    "#实验2\n",
    "# 3. 初始化神经网络\n",
    "input_size = X_train.shape[1]  # 输入层大小（特征数量）\n",
    "hidden_size = 5  # 隐藏层大小\n",
    "output_size = y_train.shape[1]  # 输出层大小（三个类别）\n",
    "learning_rate = 0.12# 学习率\n",
    "max_epochs = 10000\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "\n",
    "# 4. 训练神经网络\n",
    "nn_NSA_plus = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA_plus,nn_NSA_plus = nn_NSA_plus.train(X_train, y_train,\"NSA_plus\", epochs=max_epochs)\n",
    "\n",
    "nn_NSA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_NSA,nn_NSA = nn_NSA.train(X_train, y_train,\"NSA\", epochs=max_epochs)\n",
    "\n",
    "nn_GD = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_GD = nn_GD.train(X_train, y_train,\"GD\", epochs=max_epochs)\n",
    "\n",
    "optimizer = AdamOptimizer(learning_rate,beta1=0.5,beta2=0.5,epsilon=1e-8)\n",
    "nn_Adam = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_Adam,nn_Adam= nn_Adam.train(X_train, y_train,\"Adam\", epochs=max_epochs)\n",
    "\n",
    "optimizer = GradientDescentOptimizer(learning_rate)\n",
    "nn_FISTA = NeuralNetwork(input_size, hidden_size, output_size,optimizer, learning_rate)\n",
    "train_loss_FISTA,nn_FISTA= nn_FISTA.train(X_train, y_train,\"FISTA\", epochs=max_epochs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "ee84ebb6",
   "metadata": {},
   "outputs": [],
   "source": [
    "ind = 560\n",
    "# 创建一个示例数据\n",
    "y0 = [math.log(item) for item in train_loss_NSA_plus[0:ind]]\n",
    "y1 = [math.log(item) for item in train_loss_NSA[0:ind]]\n",
    "y2 = [math.log(item) for item in train_loss_GD[0:ind]]\n",
    "y3 = [math.log(item) for item in train_loss_Adam[0:ind]]\n",
    "y4 = [math.log(item) for item in train_loss_FISTA[0:ind]]\n",
    "x = [i for i,item in enumerate(y1)][0:ind]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "2f732b2f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA2YAAAIxCAYAAAAmKasFAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADMCUlEQVR4nOzdd3gU1f7H8fe29B5CKAm9d+liQSxcRBC7137tFa+91+tVfwr23q9dQbEhVsACooCg1NBbICGQXrf//phkNyEJJCFhk+zn9TzzzJkzZ2a/mwlhv3vOnDF5vV4vIiIiIiIiEjDmQAcgIiIiIiIS7JSYiYiIiIiIBJgSMxERERERkQBTYiYiIiIiIhJgSsxEREREREQCTImZiIiIiIhIgCkxExERERERCTAlZiIiIiIiIgGmxExERER83G53oEMQEQlK1kAHICIizUPv3r0BOPXUU/m///u/AEcTOM899xzPP/98vY6Jjo5m6dKlTRTRobNo0SJee+013nzzzSr1s2bN4s477wTg+++/p3PnzoEIT0SkVVOPmYiIiDBz5kz+9a9/sXXr1kCHIiISlNRjJiIiUouvv/6a9u3bH7CdyWQ6BNE0rczMzFr3RUVF0alTJwBsNtuhCklEJKgoMRMREalFWFgYkZGRgQ4j4MaPH8/48eMDHYaISKumoYwiIiIiIiIBph4zERFpNDt27OCdd95h4cKF7Nq1C5PJRIcOHTjiiCO4+OKLax0WWFZWxocffsh3333Hhg0bsNvtxMXFMWDAAE466SROOukkzObq3yXm5+fz7rvvMm/ePLZs2YLL5SIxMZHBgwdz6qmncswxxzTxO65ZxUQqV111FTfeeGONbS644AIWL17M0KFD+fDDD331FRNtJCcn88svv7BixQreeustlixZQl5eHomJiYwZM4bLLruM7t271xrDzp07mTFjBvPnz2fnzp243W5SU1MZN24cl1xyCXFxcVVer/JxFfG/8847jBo1qk6Tf/z000/MnDmTv//+m7y8PCIjI+nVqxcTJ07kjDPOqHEIZMXP4KqrruLf//43M2bM4LPPPmPTpk24XC46d+7MSSedxIUXXkhYWNgBfuoiIi2bEjMREWkUM2fO5KGHHsJut1ep37hxIxs3buSjjz7i4YcfZvLkyVX25+fnc+GFF5KWllalfs+ePcyfP5/58+fzySef8Morr1T5cL5jxw4uvPBCdu3aVeW4jIwMMjIy+Pbbb5k8eTLTpk1rsfeAzZw5k/vvv7/KFPaZmZnMmjWL2bNn88orrzBmzJhqx33zzTfcddddlJSUVKlfv34969evZ9asWbz55pv06tXroGMsLS3l5ptvZu7cuVXq8/LyWLx4MYsXL+aDDz7g5ZdfpmPHjjWew+l0ctlll7Fw4cIq9WlpaaSlpTFnzhzee+89oqKiDjpeEZHmSkMZRUTkoH333Xfce++92O12OnXqxBNPPMGvv/7Kr7/+yvTp00lJScFut3Prrbfy888/Vzn2iSeeIC0tjYiICO677z5++OEHfv/9dz7//HNOOeUUAH7//XfefvvtKsc98MAD7Nq1izZt2vD444/z448/smjRIj7++GPGjh0LwFdffcXXX399SH4GjS0nJ4f777+fLl268Nxzz/Hbb78xd+5cpk6disViweFwcM899+DxeKoct2zZMm666SZKSkpITU31XYt58+Zxzz33EBkZyZ49e7j22mtxOBycfPLJLFu2jCuvvBKADh06sGzZMpYtW8bw4cMPGOdNN93kS8omTJjAxx9/zB9//MGcOXO44oorsFqtrF+/nksuuYSioqIaz/HBBx+wcOFCTjnlFGbNmsXvv//OjBkzOPzwwwFYu3ZttSn8RURaGyVmIiJyUBwOBw8//DBer5fOnTszY8YMJk2aRNu2bWnbti2TJ09m5syZpKSk4PV6ue+++3A4HL7jv//+ewAuv/xyzjvvPDp16kR8fDx9+/blscceY/To0QDMnj3bd0xRUZGvd+W2225jypQppKamkpCQwJAhQ3jhhRfo2rVrtePqq6ysjOLi4v0uTqezweffH6fTSfv27ZkxYwbjx48nMTGRlJQUrrvuOi666CLAGHa4Zs2aKsc98MADeDweOnToUOVadOzYkQsuuIDHH38cgO3bt/P1119jtVqJjIz0DTU0mUxERkYSGRmJxWLZb4zz589n3rx5AFx00UU888wzDBkyhLi4OLp3787NN9/ME088AcDWrVt58cUXazxPaWkpF198MY899hj9+/cnPj6ewYMH88orr5CcnAzADz/80MCfpIhIy6ChjCIiclB+/vlndu/eDRhJUnx8fLU2CQkJ3HHHHVx33XVkZmYyf/58/vGPfwD4hj5mZ2fXeP577rmH7OxsUlNTfXVOpxOv11vrcTabjccffxyHw+Gb5r0hTjrppAO2ufPOO/nXv/7V4NfYn3PPPbfG4Xtjx4719SClp6czYMAAADZs2MC6desAuPbaa0lISKh27PHHH8+IESMwm83Vetvqa8aMGQAkJiZyyy231NhmwoQJHHvsscybN48ZM2Zw8803V0v4TCYTV1xxRbVjQ0NDOfzww/n8889JT08/qFhFRJo7JWYiInJQFi9eDBgfoiuGENbkmGOOITQ0FLvdzpIlS3yJ2YgRI/j5559577332L17NxMnTuSII44gNjYWgJ49e9KzZ88q54qPj6dHjx5s3LiR6dOns379esaPH8/o0aOJiIgAYNCgQU3xdg+pwYMH11ifmJjoK5eVlfnKixYt8pXHjRtX63nfe++9RogOlixZ4nutkJCQWttNmDCBefPmUVhYSFpaGv3796+yPyUlpcYkEvDVl5aWNkrMIiLNlRIzERE5KBUPJu7cufN+Hz5ss9no3Lkz69evrzJhx+233+6bye+HH37ghx9+wGKxMHDgQI466ihOOOEE3yyBlT3wwANcdtlllJWV8dlnn/HZZ59hs9kYOnQoY8eOZfz48VV62Rpi7ty5pKSkHNQ5DkZNvY9AlSSocq9XRc9lVFRUleStKRQVFVFYWAiw39kh992fkZFRLTGr7X2C/71W9JCKiLRWusdMREQOSsWEDhU9VfsTHh4OUGW2wO7duzN79mwuuOACXzLhdrv566+/eO655zj55JM577zz2Lx5c5VzjRgxgi+//JLTTjuN6OhowBji+Mcff/D4449z/PHHc9VVV7Fnz55GeZ+BYLXW7/vT/Px8wP9zbkrFxcW+8oGufeV4Kh9Xob7vU0SkNVJiJiIiB6XiQ/m+U7PXpCKJ2zdxSEpK4p577mHBggXMmDGDf//734wYMcL3gX3p0qX861//qvahvnPnzjz66KMsWrSId955h6uuuoqBAwf6psefP38+l19++UHfS9UUKg9BbCwVjxM4FMP+KidjB7r29UniRESClRIzERE5KB06dABg27Zt+52h0OFwsH37doBan2dlNpsZPHgw11xzDe+99x6//vqrb8r83bt3+2Zw3JfNZmPUqFHceOONfPLJJ8yfP58jjzwSMKZaX7p0aUPfXoNUPAzb5XLV2iYvL6/RX7fiWhQVFZGTk1Nruzlz5vDCCy/U+vOsi6ioKGJiYgDYtGnTfttW3l8Ro4iIVKXETEREDkrFs67sdnu1Z5RVNn/+fF/idthhhwGwYsUKzjnnHEaOHMmGDRuqHZOQkMBdd93l2664h+qnn37izDPPZNSoUb77nCpr3749N998c7XjDpWKHsHc3Nwa92dnZ7Njx45Gf92hQ4f6yr/++mut7d566y2effZZPvjgA19dfR/CbTKZGDZsGGBc28qPQNjXd999Bxi9ZY3xUGsRkdZIiZmIiByUcePGkZSUBMDjjz9eYzKSm5vL9OnTASPZOvbYYwEjgVqxYgX5+fm8++67NZ5/7dq1vnLF1PeJiYmsWLGCvLy8KslFbcd17ty5Ae+s4Spe75dffqlxWOEzzzzTJJNZDBkyhB49egDwwgsv1Ji0/vzzz6xYsQKo+jiAiins95dg7euss84CjESz4vru68cff2T+/PkAnHrqqfudIEZEJJjpblsREali69atzJw584DthgwZQs+ePQkJCeG+++5j6tSpbNu2jbPOOosbbriBkSNHAsZ0+k8//bRvGOMjjzzi61FKSkri5JNPZtasWXz88cc4nU7OOeccUlJSKC4uZvHixTz11FOAkcQdf/zxAAwcOJCRI0eyePFinnnmGfLy8jj55JNJTk4mPz+fn3/+mWeffRYwps0/1FPnH3fccaxZs4Y9e/ZwxRVXcMstt5Camsq2bdt46623+O6774iNjfVN1tGY7rnnHi655BK2bdvGP//5T2688UaGDh1KYWEh8+fP57nnngOgV69evmGiAHFxcQDs3buXn376iSFDhhAeHk5oaGitr3Xsscf6nlH29ttvk5WVxcUXX0yXLl3Yu3cvX375JW+88QYAqamp3HTTTY3+fkVEWgslZiIiUsXy5ctZvnz5AdvdeeedvueLjR8/nv/+9788+OCDbN++vcYP4BEREfznP/+p9nytu+66i82bN/PXX38xa9YsZs2aVe3YNm3a8PLLL1eZJn7atGlcdNFFbN26lTfffNP3wOXKunTp4kvQDqV//etfzJ07lzVr1rB48WJfz1KFikcAPP/8843+2ocffjiPPvoo99xzDxs3buTaa6+t1qZbt2688sorVXqvRowYgcViwe12c+WVVwLw6KOPctppp+339aZPn84tt9zCvHnz+Oabb/jmm2+qtenfvz/PPPNMjQ/LFhERgxIzERFpFGeeeSajR4/m7bffZuHChWRkZGCxWEhJSWHcuHGcffbZtG/fvtpx0dHRvP/++8ycOZNvvvmG9evXU1hYSGRkJJ06dWLcuHFceOGFvinxK7Rr147PPvuM999/n7lz57Jp0yZKSkqIjo6me/funHDCCZxzzjn77fFpKlFRUXz00Ue88847zJkzhy1btmCxWOjVqxdnnnkmp512Gi+++GKTvf4pp5zC0KFD+d///ue7FmazmW7dunHiiSdy/vnnV5sZs0ePHjz55JO88MILbNu2jbCwsFrvkassMjKSl156iblz5/Lpp5/6hphWPAR8ypQpTJw4cb8PoBYRETB59cRGERERERGRgNLkHyIiIiIiIgGmxExERERERCTAlJiJiIiIiIgEmBIzERERERGRAFNiJiIiIiIiEmCtMjHzeDw8++yzHHXUUQwePNj3oM3a5ObmcvPNNzNixAhGjBjBvffeS0lJySGMWEREREREglmrnC7/+eef54MPPuDRRx8lOTmZadOmsWPHDmbPnl3jc1QuuOAC7HY7999/PwUFBdx9992MGDGCxx57rN6vvXz5crxeb5WHdoqIiIiISPBxOp2YTCYOO+ywA7ZtdT1mDoeDN998k6lTpzJ27Fj69OnDU089xe7du/nhhx+qtV++fDmLFy/m0UcfpX///hx++OH85z//4YsvvmD37t31fn2v10tzynW9Xi8Oh6NZxSRNT9c9OOm6Bydd9+Ck6x6cdN1bnvrkBtYmjuWQS0tLo7i4mNGjR/vqYmJi6NevH0uWLOGkk06q0n7p0qUkJSXRvXt3X93IkSMxmUz8+eefTJw4sV6vX9FTNnDgwIN4F42npKSEtWvX0qNHDyIiIgIdjhwiuu7BSdc9OOm6Bydd9+Ck697yrFy5ss5tW12PWWZmJgDt27evUt+2bVsyMjKqtd+9e3e1tiEhIcTFxdXYXkREREREpLG1uh6z0tJSgGr3koWGhpKfn19j+5ruOwsNDcVutzcoBq/X22wmD6n4eVSsJTjougcnXffgpOsenHTdg5Oue8vj9XoxmUx1atvqErOwsDDAuNesogxgt9sJDw+vsb3D4ahWb7fbG9xF7HQ6Wbt2bYOObSpbt24NdAgSALruwUnXPTjpugcnXffgpOvestTUCVSTVpeYVQxLzMrKolOnTr76rKws+vTpU619u3bt+PHHH6vUORwO8vLySE5OblAMNpuNHj16NOjYxlZaWsrWrVvp0qVLjYmptE667sFJ1z046boHJ1334KTr3vJs3Lixzm1bXWLWp08foqKi+OOPP3yJWUFBAWvWrOH888+v1n7EiBFMnz6dbdu20blzZwD++OMPAIYOHdqgGEwmU7O7ITM8PLzZxSRNT9c9OOm6Bydd9+Ck6x6cdN1bjroOY4RWmJiFhIRw/vnnM336dBISEujYsSPTpk2jXbt2nHDCCbjdbnJycoiOjiYsLIzBgwczdOhQbrzxRh544AFKSkq4//77OeWUUxrcYyYiIiIiIlIfrW5WRoDrr7+eM844g3vuuYdzzjkHi8XCG2+8QUhICBkZGRx55JHMmTMHMLLY559/npSUFC666CJuuOEGjj76aB544IHAvgkREREREQkara7HDMBisXDrrbdy6623VtuXkpLCunXrqtQlJiby7LPPHqrwREREREREqmiVPWYiIiIiIiItiRIzERERERGRAFNiJiIiIiIiEmBKzERERERERAJMiZmIiIiIiEiAKTETEREREREJMCVmIiIiIiIiAabETEREREREJMCUmImIiIiIiASYErNWLi8vjz1b09n+62pKCxyBDkdERERERGqgxKwVe+6550hNSeHEM07hsgkj2R3bhbXvfBfosEREREREZB9KzFqxBQsW4PF6AVgIbCaDndPeD2xQIiIiIiJSjRKzVuyxxx6rsr0bMGfnByYYERERERGplRKzVqxLly48Ykvxbe8BbAUFgQtIRERERERqpMSsleviLPGV9wCRZUrMRERERESaGyVmrZirpIwe5Pq29wBx7lzKygIXk4iIiIiIVKfErBXb8+dq2uH1bwNtySI9PXAxiYiIiIhIdUrMWrHspWkkVdreA0RRTMqYVPjPfwIVloiIiIiI7EOJWStWuGYrYUBU+fae8nXYnnS4/34oLAxQZCIiIiIiUpkSs1bMsSUDwNdrtmffBlu2HMpwRERERESkFkrMWjHvLiMVq0jMsoEhwA8VDZSYiYiIiIg0C0rMWrFc+04eOhpCQv11fwOTAQ8oMRMRERERaSasgQ5Ams4rI9byXV8w5wEr/PV24FdgrBIzEREREZFmQT1mrVj7sO4AeKKq73sLYPPmQxqPiIiIiIjUTIlZK/bqGwsZ22YMRFbf9wngUmImIiIiItIsKDFrxWwWGzPO+4x2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33HHHfZhw4bZo6KiMpRLly6pzQswm81mHzBggL19+/b2jRs32vfs2WN/8cUX7Y0bN7YfP35cbV9IXDldvtq84LJarfZHHnnE/uCDD9o3btxo379/v33SpEn2evXq2Xfv3q22L0QsdrvdbnZyKDnParXy/vvvExERQUJCAo0bN2bcuHFUqFDB7NAkh4wePZrjx48ze/Zsx76///6biRMnsnPnTkqXLs2AAQN4/PHHHcf1uchfZsyYwQcffJDlsYcffph33nlHbV6AxcTE8N5777Fy5UpiYmIICQlh9OjRjin01fYFX61atXj77bfp3r07oDYvyM6fP8+UKVP4448/uHTpEnXr1uXll1929Hip7QsHJWYiIiIiIiIm0zNmIiIiIiIiJlNiJiIiIiIiYjIlZiIiIiIiIiZTYiYiIiIiImIyJWYiIiIiIiImU2ImIiIiIiJiMiVmIiIiIiIiJlNiJiIichtiY2Np06YNtWvXZu3atdnWadeuHcHBwRw6dChvAxQRkXxBiZmIiMht8PX1JTQ0FBcXF1599VWio6Mz1RkzZgyHDx/mrbfeIigoKM9jFBER56fETERE5DY1atSIIUOGEBUVxbhx4zIcmzNnDj/++CM9evSga9euJkUoIiLOzmK32+1mByEiIpLfpaSk0KdPH/7++28mT55Mt27d+Oeff+jduzeVK1cmLCwMb29vs8MUEREnpcRMREQkhxw+fJhu3brh6upKWFgYQ4cO5eTJk4SFhVGjRg2zwxMRESemxExERCQHhYWF8frrr+Pn58elS5eYMGECjzzyiNlhiYiIk9MzZiIiIjmoZ8+eNG3alEuXLnHXXXcpKRMRkRuixExERCQHHThwgG3btgGwbds2Nm/ebHJEIiKSHygxExERySGJiYkMHz6cpKQkRo4cidVqZeTIkcTGxpodmoiIODklZiIiIjlk4sSJ7N27lyFDhjBo0CB69+7N8ePHefPNN80OTUREnJwSMxERkRzw008/MW/ePBo2bMizzz4LwOjRowkKCmLp0qUsXbrU5AhFRMSZaVZGERGR23Ts2DG6deuGzWZj0aJFVKpUyXHs77//pk+fPnh7e7N48WLKly9vYqQiIuKs1GMmIiJyG1JSUhgxYgQxMTGMGzcuQ1IG0KBBA5555hliYmIcz52JiIhcTYmZiIjIbXj//ffZunUrnTt3plu3blnWGTp0KMHBwWzevJnPPvssbwMUEZF8QUMZRURERERETKYeMxEREREREZMpMRMRERERETGZEjMRERERERGTKTETERERERExmRIzERERERERkykxExERERERMZkSMxEREREREZMpMRMRERERETGZEjMRERERERGTKTETERERERExmRIzERERERERkykxExERERERMZkSMxEREREREZP9Py8c6HcFZN5FAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "# 使用 seaborn 设置美化参数\n",
    "sns.set(style=\"whitegrid\")\n",
    "\n",
    "# 创建一个新的图形\n",
    "plt.figure(figsize=(10, 6))\n",
    "\n",
    "# 绘制折线图\n",
    "plt.plot(x, y0, color='orange', linewidth=2, linestyle='-',label=\"NSA_plus\")\n",
    "plt.plot(x, y1, color='blue', linewidth=2, linestyle='-', label=\"NSA\")\n",
    "plt.plot(x, y2, color='red', linewidth=2, linestyle='-', label=\"GD\")\n",
    "plt.plot(x, y3, color='green', linewidth=2, linestyle='-', label=\"Adam\")\n",
    "plt.plot(x, y4, color='black', linewidth=2, linestyle='-', label=\"FISTA\")\n",
    "#plt.plot(x, y0, color='yellow', linewidth=2, linestyle='-', marker='o', markersize=5, markerfacecolor='yellow', markeredgecolor='yellow',label=\"NSA_plus\")\n",
    "#plt.plot(x, y1, color='blue', linewidth=2, linestyle='-', marker='o', markersize=5, markerfacecolor='blue', markeredgecolor='blue',label=\"NSA\")\n",
    "#plt.plot(x, y2, color='red', linewidth=2, linestyle='-', marker='o', markersize=5, markerfacecolor='red', markeredgecolor='red',label=\"GD\")\n",
    "#plt.plot(x, y3, color='green', linewidth=2, linestyle='-', marker='o', markersize=5, markerfacecolor='green', markeredgecolor='green',label=\"Adam\")\n",
    "#plt.plot(x, y4, color='black', linewidth=2, linestyle='-', marker='o', markersize=5, markerfacecolor='black', markeredgecolor='black',label=\"FISTA\")\n",
    "# 添加标题和标签\n",
    "plt.title('Loss Function', fontsize=20)\n",
    "plt.xlabel('X', fontsize=14)\n",
    "plt.ylabel('Y', fontsize=14)\n",
    "\n",
    "# 显示网格\n",
    "plt.grid(True)\n",
    "plt.legend()\n",
    "# 显示图形\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "7b3d1e19",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7.218833535886177e-14\n",
      "2.7814275183585402e-14\n",
      "1.7552948539680034e-07\n"
     ]
    }
   ],
   "source": [
    "print(np.mean(np.square(y_train - nn_NSA_plus.predict(X_train))))\n",
    "print(np.mean(np.square(y_train - nn_NSA.predict(X_train))))\n",
    "print(np.mean(np.square(y_train - nn_GD.predict(X_train))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5efdfc00",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "测试集模型准确率: 100.00%\n",
      "\n",
      "训练集模型准确率: 100.00%\n"
     ]
    }
   ],
   "source": [
    "predictions_test = nn_NSA_plus.predict(X_test)\n",
    "predicted_classes_test = np.argmax(predictions_test, axis=1)\n",
    "true_classes_test = np.argmax(y_test, axis=1)\n",
    "print(f\"\\n测试集模型准确率: {np.mean(predicted_classes_test == true_classes_test) * 100:.2f}%\")\n",
    "\n",
    "predicteds_train = nn_NSA_plus.predict(X_train)\n",
    "predicted_classes_train = np.argmax(predicteds_train, axis=1)\n",
    "true_classes_train = np.argmax(y_train,axis=1)\n",
    "print(f\"\\n训练集模型准确率: {np.mean(predicted_classes_train == true_classes_train) * 100:.2f}%\")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
